package com.iwthings.speex;


import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import android.annotation.SuppressLint;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;

public class SpeexPlayer extends Thread
{

    static AudioTrack Track = null;
    
    private static List<short[]> m_list = null; 
    download mThDownload = null;

	@SuppressLint("NewApi")
	public int OpenAudioTrack(int userid, String ip, int port)
	{
		 String strip;
			try {
				InetAddress myServer = InetAddress.getByName(ip);
				strip = myServer.getHostAddress();	
			} catch (UnknownHostException e) {
				strip = "124.202.151.53";
			}
			
		mThDownload = new download();
		int iRet = SpeexJni.GetInstance().OpenSpeexDecoder(userid, strip, port);	
		if(iRet < 0)
		{
			return -1;
		}
		m_list = Collections.synchronizedList(new LinkedList<short[]>());
    
		int bufferSizeInBytes = AudioTrack.getMinBufferSize(8000,  AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT); 
		Track = new AudioTrack(
					AudioManager.STREAM_MUSIC,
					8000,
					 AudioFormat.CHANNEL_OUT_MONO,
					AudioFormat.ENCODING_PCM_16BIT,
					bufferSizeInBytes,
					AudioTrack.MODE_STREAM);

		if(Track == null)
		{
			return -1;
		}
		Track.play(); 
		this.start();
		
		mThDownload.start();
		
		return 0;
	}
	
	public int CloseAudioTrack()
	{
		SpeexJni.GetInstance().CloseSpeexDecoder();
		while(true)
		{
		  if(this.isAlive())
		  {
			  this.interrupt();
		  }
		  else
		  {
			  break;
		  }
		} 
		
		if(Track != null)
		{
			Track.stop();
			Track.release();
			Track = null;
		}
		return 0;
	}
		
	public static  void PlayAudio(short[] data, int datalen)
	{
		
		short[] playbuf = new short[datalen];
		System.arraycopy(data, 0, playbuf, 0, datalen);
		calc1(playbuf, 0 , datalen);
		if(m_list.size() > 150)
		{
			m_list.clear();
		}
		m_list.add(playbuf);
		
	}
	
	public void run()
	{
		while(!this.isInterrupted())
		{
			
			if(Track != null)
			{
				if(!m_list.isEmpty())
				{
					short[] playbuf = (short[])m_list.get(0);
					m_list.remove(0);
					SpeexCache.GetInstance().AddCache(playbuf, playbuf.length);
					Track.write(playbuf, 0, playbuf.length);	
				}
				else
				{
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
	
	static void calc1(short[] lin,int off,int len) 
	{
		 int i,j;

		 for (i = 0; i < len; i++)
		 {
			 j = lin[i+off];
			 lin[i+off] = (short)(j>>2);
		 }
	}

	class download extends Thread
	{
		public void run()
		{
			SpeexJni.GetInstance().SpeexDecoder();
		}
	}
}
